#include "SQLPartitionByRange.h"
#include "../../sql/ast/SQLPartition.h"
#include "../../sql/ast/expr/SQLIntegerExpr.h"
#include "../../sql/visitor/SQLASTVisitor.h"
#include "../../utils/listTran.h"
#include "../../utils/log.h"
#include "SQLSubPartitionBy.h"

SQLPartitionByRange::SQLPartitionByRange()
{
}

SQLExpr_ptr SQLPartitionByRange::getInterval()
{
  return interval;
}

void SQLPartitionByRange::setInterval(SQLExpr_ptr interval)
{
  if (interval != nullptr)
  {
    interval->setParent(SharedObject(SQLPartitionByRange));
  }

  this->interval = interval;
}

SQLExpr_ptr SQLPartitionByRange::getStartWith()
{
  return this->startWith;
}

void SQLPartitionByRange::setStartWith(SQLExpr_ptr startWith)
{
  if (startWith != nullptr)
  {
    startWith->setParent(SharedObject(SQLPartitionByRange));
  }

  this->startWith = startWith;
}

SQLIntegerExpr *SQLPartitionByRange::getExpireAfter()
{
  return this->expireAfter;
}

void SQLPartitionByRange::setExpireAfter(SQLIntegerExpr *expireAfter)
{
  if (expireAfter != nullptr)
  {
    expireAfter->setParent(SharedObject(SQLPartitionByRange));
  }
  this->expireAfter = expireAfter;
}

SQLIntegerExpr *SQLPartitionByRange::getPreAllocate()
{
  return this->preAllocate;
}

void SQLPartitionByRange::setPreAllocate(SQLIntegerExpr *preAllocate)
{
  if (preAllocate != nullptr)
  {
    preAllocate->setParent(SharedObject(SQLPartitionByRange));
  }
  this->preAllocate = preAllocate;
}

SQLExpr_ptr SQLPartitionByRange::getPivotDateExpr()
{
  return this->pivotDateExpr;
}

void SQLPartitionByRange::setPivotDateExpr(SQLExpr_ptr pivotDateExpr)
{
  if (pivotDateExpr != nullptr)
  {
    pivotDateExpr->setParent(SharedObject(SQLPartitionByRange));
  }
  this->pivotDateExpr = pivotDateExpr;
}

// @Override
void SQLPartitionByRange::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLPartitionByRange)))
  {
    SQLObject_list_ptr  tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(columns);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, interval);
    acceptChild(visitor, SQLIntegerExpr_ptr(expireAfter));
    acceptChild(visitor, SQLIntegerExpr_ptr(preAllocate));
    acceptChild(visitor, pivotDateExpr);
    SQLObject_list_ptr  tmp2 = ListTran::tran_class<SQLExpr, SQLObject>(columns);
    acceptChild(visitor, tmp2);
    SQLObject_list_ptr  tmp3 = ListTran::tran_class<SQLName, SQLObject>(storeIn);
    acceptChild(visitor, tmp3);
    SQLObject_list_ptr  tmp4 = ListTran::tran_class<SQLPartition, SQLObject>(partitions);
    acceptChild(visitor, tmp4);
    acceptChild(visitor, SQLSubPartitionBy_ptr(subPartitionBy));
  }
  visitor->endVisit(SharedObject(SQLPartitionByRange));
}

SQLObject_ptr SQLPartitionByRange::clone()
{
  SQLObject_ptr clone_tmp = SQLPartitionByRange_ptr(new SQLPartitionByRange());
  SQLPartitionByRange_ptr x = std::dynamic_pointer_cast<SQLPartitionByRange>(clone_tmp);
  // SQLPartitionByRange *x = new SQLPartitionByRange();

  this->cloneTo(x);

  if (interval != nullptr)
  {
    x->setInterval(std::dynamic_pointer_cast<SQLExpr>(interval->clone()));
  }

  if (startWith != nullptr)
  {
    x->setStartWith(std::dynamic_pointer_cast<SQLExpr>(startWith->clone()));
  }

  if (expireAfter != nullptr)
  {
    x->setExpireAfter(std::dynamic_pointer_cast<SQLIntegerExpr>(expireAfter->clone()).get());
  }

  for (SQLExpr_ptr column : *columns)
  {
    SQLExpr_ptr c2 = std::dynamic_pointer_cast<SQLExpr>(column->clone());
    c2->setParent(x);
    x->columns->push_back(c2);
  }

  x->setColumns(this->isColumns_);
  x->setDisableSchedule(this->disableSchedule);

  return x;
}

void SQLPartitionByRange::cloneTo(SQLPartitionByRange_ptr x)
{
  SQLPartitionBy::cloneTo(x);
}

BOOL_ptr SQLPartitionByRange::isColumns()
{
  return isColumns_;
}

void SQLPartitionByRange::setColumns(BOOL_ptr columns)
{
  isColumns_ = columns;
}

BOOL_ptr SQLPartitionByRange::isDisableSchedule()
{
  return this->disableSchedule;
}

void SQLPartitionByRange::setDisableSchedule(BOOL_ptr disableSchedule)
{
  this->disableSchedule = disableSchedule;
}
